

struct stackframe {	/* proc_ptr points here				↑ Low			*/
	u32	gs;		/* ┓						│			*/
	u32	fs;		/* ┃						│			*/
	u32	es;		/* ┃						│			*/
	u32	ds;		/* ┃						│			*/
	u32	edi;		/* ┃						│			*/
	u32	esi;		/* ┣ pushed by save()				│			*/
	u32	ebp;		/* ┃						│			*/
	u32	kernel_esp;	/* <- 'popad' will ignore it			│			*/
	u32	ebx;		/* ┃						↑栈从高地址往低地址增长*/		
	u32	edx;		/* ┃						│			*/
	u32	ecx;		/* ┃						│			*/
	u32	eax;		/* ┛						│			*/
	u32	retaddr;	/* return address for assembly code save()	│			*/
	u32	eip;		/*  ┓						│			*/
	u32	cs;		/*  ┃						│			*/
	u32	eflags;		/*  ┣ these are pushed by CPU during interrupt	│			*/
	u32	esp;		/*  ┃						│			*/
	u32	ss;		/*  ┛						┷High			*/
};


struct proc {
	struct stackframe regs; // 要保存的寄存器

	u16 ldt_sel; // LDT 选择子
	struct descriptor ldts[LDT_SIZE]; // LDT 描述符

	int ticks; // 由某个值递减到 0
	int priority; // 若 ticks 递减到 0，则 ticks = priority

	u32 pid; // 进程ID
	char name[16]; // 进程名

	int  p_flags; // 标明进程状态。可取值为：
				  // 0: 表示进程正在运行或准备运行
				  // SENDING: 进程处于发送消息的状态。由于消息还未送达，进程被阻塞。
				  // RECEIVING: 进程处于接收消息的状态。由于消息还未收到，进程被阻塞。

	MESSAGE * p_msg; // 指向消息体的指针
	int p_recvfrom; // 收到消息，该成员记录发送方是谁
	int p_sendto;   // 发送消息，该成员记录要发送的对象是谁

	int has_int_msg; // 如果在任务未准备好处理时发生中断，则非零。（当发生中断，而这个中断需要某个进程来处理，则该成员不为 0）

	struct proc * q_sending; // 向此 proc 发送消息的 procs 队列
	struct proc * next_sending; // 发送队列中的下一个过程 (q_sending)

	int nr_tty; // 该进程对应的控制台
};

struct task {
	task_f	initial_eip;
	int	stacksize;
	char	name[32];
};

#define proc2pid(x) (x - proc_table)

/* Number of tasks & procs */
#define NR_TASKS	4 // 系统进程
#define NR_PROCS	3 // 用户进程
#define FIRST_PROC	proc_table[0]
#define LAST_PROC	proc_table[NR_TASKS + NR_PROCS - 1]

/* stacks of tasks */
#define STACK_SIZE_TTY		0x8000
#define STACK_SIZE_SYS		0x8000
#define STACK_SIZE_FS		0x8000
#define STACK_SIZE_HD		0x8000
#define STACK_SIZE_TESTA	0x8000
#define STACK_SIZE_TESTB	0x8000
#define STACK_SIZE_TESTC	0x8000

#define STACK_SIZE_TOTAL	(STACK_SIZE_TTY + \
				STACK_SIZE_SYS + \
				STACK_SIZE_FS + \
				STACK_SIZE_HD + \
				STACK_SIZE_TESTA + \
				STACK_SIZE_TESTB + \
				STACK_SIZE_TESTC)


